package com.skt.controller;

import com.skt.domain.DTO.TenantOrderQueryRequest;
import com.skt.domain.DTO.request.OrderCreateRequest;
import com.skt.domain.VO.OrderCreateResultVO;
import com.skt.domain.VO.OrderDetailVO;
import com.skt.exception.*;
import com.skt.result.PageResult;
import com.skt.service.TenantOrderService;
import com.skt.utils.LogUtil;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

@RestController
@RequiredArgsConstructor
@RequestMapping("/orders")
@Tag(name = "订单管理接口", description = "用户创建租赁订单相关操作")
public class TenantOrderController {

    private final TenantOrderService tenantOrderService;

    @Operation(
            summary = "创建租赁订单",
            description = "用户提交租赁商品订单请求，系统校验库存、价格、用户状态等信息后生成待支付订单。订单创建成功后需在规定时间内完成支付，否则自动取消。"
    )
    @ApiResponses({
            @ApiResponse(responseCode = "201", description = "订单创建成功，返回订单详情"),
            @ApiResponse(responseCode = "400", description = "请求参数错误，如商品ID无效、数量不合法、地址缺失等"),
            @ApiResponse(responseCode = "401", description = "未授权访问，用户未登录或token失效"),
            @ApiResponse(responseCode = "403", description = "权限不足，如尝试为他人下单或账号受限"),
            @ApiResponse(responseCode = "404", description = "请求的商品或商家不存在"),
            @ApiResponse(responseCode = "409", description = "业务冲突，如库存不足、商品已下架、重复下单等"),
            @ApiResponse(responseCode = "500", description = "服务器内部处理错误")
    })
    @PostMapping
    public ResponseEntity<OrderCreateResultVO> createOrder(
            @Parameter(description = "订单创建请求参数", required = true)
            @Valid @RequestBody OrderCreateRequest createRequest) {

        LogUtil.setTraceId();
        LogUtil.startTimer("ORDER_CREATE");

        try {
            OrderCreateResultVO result = tenantOrderService.createOrder(createRequest);
            return ResponseEntity.status(HttpStatus.CREATED).body(result);
        } catch (BusinessException e) {
            LogUtil.error("ORDER", "CREATE", "创建订单业务异常", e);
            throw e;
        } catch (Exception e) {
            LogUtil.error("ORDER", "CREATE", "创建订单系统异常", e);
            throw OrderException.of(OrderErrorCode.CREATE_ORDER_FAILED, "创建订单失败");
        } finally {
            LogUtil.stopTimer();
            LogUtil.clearContext();
        }
    }


    @Operation(
            summary = "查询订单详情",
            description = "根据订单ID获取指定租赁订单的详细信息，包括商品信息、租期、价格、状态、收货地址等。仅限订单所属用户或系统管理员访问。"
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "成功返回订单详情"),
            @ApiResponse(responseCode = "400", description = "请求参数错误，如订单ID格式无效"),
            @ApiResponse(responseCode = "401", description = "未授权访问，用户未登录或token失效"),
            @ApiResponse(responseCode = "403", description = "权限不足，非订单所属用户且非管理员"),
            @ApiResponse(responseCode = "404", description = "订单不存在"),
            @ApiResponse(responseCode = "500", description = "服务器内部处理错误")
    })
    @GetMapping("/{id}")
    public ResponseEntity<OrderDetailVO> getOrderDetail(
            @Parameter(description = "订单ID", required = true, example = "1234567890")
            @PathVariable("id") String orderId) {

        LogUtil.setTraceId();
        LogUtil.startTimer("ORDER_DETAIL");

        try {
            OrderDetailVO detail = tenantOrderService.getOrderDetail(orderId);
            return ResponseEntity.ok(detail);
        } catch (BusinessException e) {
            LogUtil.error("ORDER", "DETAIL", "查询订单详情业务异常", e);
            throw e;
        } catch (Exception e) {
            LogUtil.error("ORDER", "DETAIL", "查询订单详情系统异常", e);
            throw OrderException.of(OrderErrorCode.QUERY_ORDER_LIST_FAILED, "查询订单详情失败");
        } finally {
            LogUtil.stopTimer();
            LogUtil.clearContext();
        }
    }


    @Operation(
            summary = "查询我的订单列表",
            description = "获取当前登录用户的订单列表，支持按订单状态、分页等条件查询。"
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "成功返回订单分页列表"),
            @ApiResponse(responseCode = "400", description = "请求参数错误"),
            @ApiResponse(responseCode = "401", description = "未授权访问"),
            @ApiResponse(responseCode = "403", description = "权限不足"),
            @ApiResponse(responseCode = "500", description = "服务器内部错误")
    })
    @GetMapping
    public ResponseEntity<PageResult<OrderDetailVO>> getMyOrderList(
            @Parameter(description = "订单查询条件", required = true)
            @Valid TenantOrderQueryRequest queryRequest) {

        LogUtil.setTraceId();
        LogUtil.startTimer("ORDER_LIST");

        try {
            PageResult<OrderDetailVO> result = tenantOrderService.getMyOrderList(queryRequest);
            return ResponseEntity.ok(result);
        } catch (BusinessException e) {
            LogUtil.error("ORDER", "LIST", "查询订单列表业务异常", e);
            throw e;
        } catch (Exception e) {
            LogUtil.error("ORDER", "LIST", "查询订单列表系统异常", e);
            throw OrderException.of(OrderErrorCode.QUERY_ORDER_LIST_FAILED, "查询订单列表失败");
        } finally {
            LogUtil.stopTimer();
            LogUtil.clearContext();
        }
    }


    @Operation(
            summary = "取消订单",
            description = "用户取消处于“待支付”状态的租赁订单。仅允许订单所属用户操作，且订单必须为可取消状态（如已支付则不可取消）。重复取消请求将幂等返回成功。"
    )
    @ApiResponses({
            @ApiResponse(responseCode = "200", description = "订单取消成功，返回更新后的订单状态"),
            @ApiResponse(responseCode = "400", description = "请求参数错误或订单状态不允许取消（如已支付、已发货等）"),
            @ApiResponse(responseCode = "401", description = "未授权访问，用户未登录或token失效"),
            @ApiResponse(responseCode = "403", description = "权限不足，非订单所属用户"),
            @ApiResponse(responseCode = "404", description = "订单不存在"),
            @ApiResponse(responseCode = "500", description = "服务器内部处理错误")
    })
    @PostMapping("/{id}/cancel")
    public ResponseEntity<OrderDetailVO> cancelOrder(
            @Parameter(description = "订单编号（orderNo）", required = true, example = "R20251127091530123")
            @PathVariable("id") String orderNo) {

        LogUtil.setTraceId();
        LogUtil.startTimer("ORDER_CANCEL");

        try {
            OrderDetailVO result = tenantOrderService.cancelOrder(orderNo);
            return ResponseEntity.ok(result);
        } catch (BusinessException e) {
            LogUtil.error("ORDER", "CANCEL", "取消订单业务异常", e);
            throw e;
        } catch (Exception e) {
            LogUtil.error("ORDER", "CANCEL", "取消订单系统异常", e);
            throw OrderException.of(OrderErrorCode.CANCEL_ORDER_FAILED, "取消订单失败");
        } finally {
            LogUtil.stopTimer();
            LogUtil.clearContext();
        }
    }
}